package com.jltx.xq.coroutinesandrxpro.rxjava

import android.annotation.SuppressLint
import android.util.Log
import io.reactivex.Completable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers

/**
 * @author aidenquan
 *         Created by junlintianxia on 2021/07/26.
 */
object RxJava2Learn1 {

    @SuppressLint("CheckResult")
    fun initializeObjects() {
        initializeObjectsAsync()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                Log.d(TAG, "Rx heavyInitialization success ${Thread.currentThread()}")
            }, {
                Log.d(TAG, "Rx heavyInitialization fail $it ${Thread.currentThread()}")
            })
    }

    private fun initializeObjectsAsync(): Completable {
        return Completable.create { emitter ->
            try {
                heavyInitialization()
                if (!emitter.isDisposed) {
                    emitter.onComplete()
                }
            } catch (e: Exception) {
                emitter.onError(e)
            }
        }
    }

    private fun initializeObjectsAsyncCallable(): Completable {
        return Completable.fromCallable {
            heavyInitialization()
        }
    }

    fun heavyInitialization() {
//        throw Exception("heavyInitialization error")
        Log.d(TAG, "heavyInitialization ${Thread.currentThread()}")
    }

    fun fib(n: Long): Long {
        return if (n <= 1) n
        else fib(n - 1) + fib(n - 2)
    }

    @SuppressLint("CheckResult")
    fun fibonacciAsync() {
        fibonacciAsync(10)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                Log.d(TAG, "Rx fibonacciAsync success $it ${Thread.currentThread()}")
            }, {
                Log.d(TAG, "Rx fibonacciAsync fail $it ${Thread.currentThread()}")
            })
    }


    private fun fibonacciAsync(number: Long): Single<Long> =
        Single.create { emitter ->
            val result = fib(number)
            if (emitter != null && !emitter.isDisposed) {
                emitter.onSuccess(result)
            }
        }

    const val TAG = "CorAndRxjava2"
}